package com.xiaoye.qbproject.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xiaoye.qbproject.domain.*;
import com.xiaoye.qbproject.enums.SearchType;
import com.xiaoye.qbproject.mapper.*;
import com.xiaoye.qbproject.service.*;
import com.xiaoye.qbproject.util.StringUtils;
import com.xiaoye.qbproject.vo.QaSearchRes;
import com.xiaoye.qbproject.vo.QaVo;
import io.jsonwebtoken.lang.Collections;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;

import javax.servlet.http.HttpServletRequest;
import java.io.StringReader;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class QaServiceImpl implements QaService {
    @Autowired
    private ZbInfoService zbInfoService;
    @Autowired
    BlbcTroopsService blbcTroopsService;
    @Autowired
    private BlbcTroopsMapper blbcTroopsMapper;
    @Autowired
    private CountryRegionService countryRegionService;
    @Autowired
    private QbWarfareExamplesService qbWarfareExamplesService;
    @Autowired
    private QbWarfareExamplesMapper qbWarfareExamplesMapper;
    @Autowired
    private QbWarfareService qbWarfareService;
    /**
     * 国家和地区
     */
    private static final List<String> COUNTRY_REGIONS = Arrays.asList("中国", "美国", "印度", "台湾", "韩国");
    @Autowired
    private ZbInfoMapper zbInfoMapper;
    @Autowired
    private CountryRegionMapper countryRegionMapper;
    @Autowired
    private QbWarfareMapper qbWarfareMapper;

    @SneakyThrows
    @Override
    public String qa(QaVo qaVo, HttpServletRequest request) {
        // 1. 获取问题
        String problem = qaVo.getProblem();
        Boolean isAccurateSearch = qaVo.getIsAccurateSearch();
        if (Boolean.TRUE.equals(isAccurateSearch)) {
            // 精确匹配
            String searchType = qaVo.getSearchType();
            if (SearchType.ZL.name().equals(searchType)) {
                return matchZlAccurateSearch(qaVo);
            } else if (SearchType.BLBC.name().equals(searchType)) {
                return matchBlbcAccurateSearch(qaVo);
            } else if (SearchType.ZB.name().equals(searchType)) {
                return matchZbAccurateSearch(qaVo);
            }

        }

        // 2. 分词
        IKSegmenter ikSegmenter = new IKSegmenter(new StringReader(problem), true);

        // 2.1 获取分词结果
        List<String> words = new ArrayList<>();
        Lexeme next = ikSegmenter.next();
        while (next != null) {
            words.add(next.getLexemeText());
            next = ikSegmenter.next();
        }
        log.info("分词结果：{}", words);

        String answer;
        // 3. 检索
        // 3.1 战例匹配
        answer = matchWarfareExamples(words);
        if (StringUtils.isNotEmpty(answer)) {
            return answer;
        }
        // 3.2 装备参数匹配
        answer = matchZb(words);
        if (StringUtils.isNotEmpty(answer)) {
            return answer;
        }
        // 3.3 兵力编程编组 匹配


        answer = matchBlbc(words);
        if (StringUtils.isNotEmpty(answer)) {
            return answer;
        }
        // 4. 返回结果
        return null;
    }

    @Override
    public List<QaSearchRes> getSearch(String keyword) {
        List<QaSearchRes> searchResList = new ArrayList<>();
        // 1. 检索战例
        qbWarfareMapper.selectList(Wrappers.lambdaQuery(QbWarfare.class).like(QbWarfare::getName, keyword)).forEach(item -> searchResList.add(new QaSearchRes(item.getName(), SearchType.ZL.name())));
        qbWarfareExamplesMapper.selectList(Wrappers.lambdaQuery(QbWarfareExamples.class).like(QbWarfareExamples::getTitle, keyword).or().like(QbWarfareExamples::getName, keyword)).forEach(item -> {
            searchResList.add(new QaSearchRes(item.getTitle(), SearchType.ZL.name()));
            searchResList.add(new QaSearchRes(item.getName(), SearchType.ZL.name()));
        });
        // 2. 检索装备参数
        zbInfoMapper.selectList(Wrappers.lambdaQuery(ZbInfo.class).like(ZbInfo::getName, keyword)).forEach(item -> searchResList.add(new QaSearchRes(item.getName(), SearchType.ZB.name())));
        // 3. 检索兵力编程编组
        blbcTroopsMapper.selectList(Wrappers.lambdaQuery(BlbcTroops.class).like(BlbcTroops::getTroopsName, keyword)).forEach(item -> searchResList.add(new QaSearchRes(item.getTroopsName(), SearchType.BLBC.name())));
        // searchResList 根据 accurateSearch去重
        ArrayList<QaSearchRes> qaSearchRes = new ArrayList<>(searchResList.stream()
                .collect(Collectors.toMap(
                        QaSearchRes::getAccurateSearch,  // keyMapper - 用于生成Map的键
                        result -> result,       // valueMapper - 用于生成Map的值，这里直接使用原对象
                        (existing, replacement) -> existing  // mergeFunction - 如果键冲突，选择保留哪个值，这里保留现有的
                ))
                .values());
        return qaSearchRes;
    }

    /**
     * 根据传入的QA对象进行精确搜索匹配。
     *
     * @param qaVo QA对象，包含需要精确搜索的内容。
     * @return 匹配结果字符串。
     */
    private String matchZbAccurateSearch(QaVo qaVo) {
        String accurateSearch = qaVo.getAccurateSearch();
        return matchZb(java.util.Collections.singletonList(accurateSearch));

    }

    /**
     * 精确匹配blbc搜索
     *
     * @param qaVo 包含搜索信息的对象
     * @return 匹配结果
     */
    private String matchBlbcAccurateSearch(QaVo qaVo) {
        String accurateSearch = qaVo.getAccurateSearch();
        String problem = qaVo.getProblem();
        ArrayList<String> words = new ArrayList<>();
        words.add(accurateSearch);
        if (problem.contains("下级") || problem.contains("下属") || problem.contains("下面")) {
            words.add("下属");
        } else if (problem.contains("上级") || problem.contains("上层") || problem.contains("领导单位") || problem.contains("归属")) {
            words.add("上级");
        }
        if (problem.contains(COUNTRY_REGIONS.get(0))) {
            words.add(COUNTRY_REGIONS.get(0));
        } else if (problem.contains(COUNTRY_REGIONS.get(1))) {
            words.add(COUNTRY_REGIONS.get(1));
        } else if (problem.contains(COUNTRY_REGIONS.get(2))) {
            words.add(COUNTRY_REGIONS.get(2));
        } else if (problem.contains(COUNTRY_REGIONS.get(3))) {
            words.add(COUNTRY_REGIONS.get(3));
        } else if (problem.contains(COUNTRY_REGIONS.get(4))) {
            words.add(COUNTRY_REGIONS.get(4));
        }

        return matchBlbc(words);
    }

    /**
     * 通过精确搜索匹配战争案例
     *
     * @param qaVo 包含精确搜索信息的对象
     * @return 匹配到的战争案例字符串
     */
    private String matchZlAccurateSearch(QaVo qaVo) {
        String accurateSearch = qaVo.getAccurateSearch();
        ArrayList<String> words = new ArrayList<>();
        words.add(accurateSearch);
        if (qaVo.getProblem().contains("战役") || qaVo.getProblem().contains("战斗")) {
            words.add("战役");
        }
        return matchWarfareExamples(java.util.Collections.singletonList(accurateSearch));
    }


    private String matchBlbc(List<String> words) {
        words.remove("单位");
        List<String> cournties = COUNTRY_REGIONS.stream().filter(words::contains).collect(Collectors.toList());
        // 国家匹配
        String country = cournties.isEmpty() ? null : cournties.get(0);
        // 当前层级
        List<BlbcTroops> blbcTroops = blbcTroopsMapper.getBlbcInfoByNames(words, country);
        if (Collections.isEmpty(blbcTroops)) {
            log.info("未匹配到编程编组:{}", words);
            return null;
        }
        StringBuilder res = new StringBuilder();
        for (BlbcTroops troop : blbcTroops) {
            // 自身描述
            res.append(troop.getTroopsName());
            if (!StringUtils.isBlank(troop.getAbbreviation())) {
                res.append("简称:  ").append(troop.getAbbreviation());
            }
            res.append("\n");
            String summary = troop.getSummary();
            if (StringUtils.isNotEmpty(summary)) {
                res.append("简介:  ").append(StringUtils.isBlank(summary) ? "无" : summary).append("\n");
            }

            if (words.contains("下级") || words.contains("下属") || words.contains("下面")) {
                //  查询下级单位
                List<BlbcTroops> troopList = blbcTroopsService.list(Wrappers.<BlbcTroops>lambdaQuery().eq(BlbcTroops::getParentId, troop.getId()));
                if (!Collections.isEmpty(troopList)) {
                    res.append("\n").append("下属单位:").append("\n");
                    for (BlbcTroops sub : troopList) {
                        res.append(sub.getTroopsName());
                        if (!StringUtils.isBlank(sub.getAbbreviation())) {
                            res.append("简称:  ").append(sub.getAbbreviation());
                        }
                        res.append("\n");
                        res.append("简介:  ").append(StringUtils.isBlank(sub.getSummary()) ? "无" : sub.getSummary()).append("\n");
                    }
                } else {
                    res.append("无下属:").append("\n");
                    return null;
                }

            } else if (words.contains("上级") || words.contains("上层") || words.contains("领导单位") || words.contains("归属")) {
                String parentId = troop.getParentId();
                if (StringUtils.isBlank(parentId)) {
                    log.info("无上级:{}", words);
                    res.append("无上级:").append("\n");
                    return null;
                }
                // 上级
                List<BlbcTroops> troopList = blbcTroopsService.list(Wrappers.<BlbcTroops>lambdaQuery().eq(BlbcTroops::getId, parentId));
                res.append("上级:").append("\n");
                for (BlbcTroops parent : troopList) {
                    res.append(parent.getTroopsName());
                    if (!StringUtils.isBlank(parent.getAbbreviation())) {
                        res.append("简称:  ").append(parent.getAbbreviation());
                    }
                    res.append("\n");
                    res.append("简介:  ").append(StringUtils.isBlank(parent.getSummary()) ? "无" : parent.getSummary()).append("\n");
                }
            }
        }

        return res.toString();
    }

    @Autowired
    private ZbModuleMapper zbModuleMapper;

    private String matchZb(List<String> words) {
        // 查询匹配到的装备名称
        List<ZbInfo> zbInfos = zbInfoMapper.getZbInfoByNames(words);
        if (Collections.isEmpty(zbInfos)) {
            log.info("未匹配到装备参数:{}", words);
            return null;
        }
        StringBuilder res = new StringBuilder();
        if (zbInfos.size() > 1) {
            res.append("匹配到多个装备信息:").append("\n").append("\n").append("\n").append("\n");
        }
        for (ZbInfo zbInfo : zbInfos) {
            // 装备信息描述 拼接
            res.append("装备名称: ").append(zbInfo.getName()).append("\n").append("\n");
            List<ZbAttr> attrs = zbInfo.getAttrs();
            res.append("装备特征: ");
            if (!Collections.isEmpty(attrs)) {
               /* res.append("\n");
                res.append(JSON.toJSONString(attrs));
                res.append("\n");*/
                List<ZbAttr> zbAttrs = JSONArray.parseArray(JSONArray.toJSONString(attrs), ZbAttr.class);
                for (ZbAttr attr : zbAttrs) {
                    res.append(attr.getAttrName()).append(String.join(";", attr.getAttrs()))
                            .append("\n");
                }
            } else {
                res.append("[暂无装备特征信息]");
            }
            res.append("\n").append("\n");

            // 查询模块信息
            List<ZbModule> zbModules = zbModuleMapper.selectList(Wrappers.lambdaQuery(ZbModule.class).eq(ZbModule::getZbInfoId, zbInfo.getId()));
            if (!Collections.isEmpty(zbModules)) {
                // 加上模块信息描述
                res.append("\n").append("\n");
                for (ZbModule zbModule : zbModules) {
                    res.append("模块名称: ").append(zbModule.getName()).append("\n");
                    res.append("参数: ").append(zbModule.getParameter()).append("\n");
                }
            }


        }

        return res.toString();
    }

    /**
     * @param words
     * @description: 战例匹配
     * @author: ChenYao
     * @return: java.lang.String
     * @ceateDate: 2025/1/19 下午9:36
     */

    private String matchWarfareExamples(List<String> words) {
        // 获取所有的战争名称
        List<String> warfareName = qbWarfareService.getAllWarfareName();

        if (!Collections.isEmpty(warfareName)) {
            //  匹配一下 战争名称 集合是否有交集
            Set<String> wordSet = new HashSet<>(words);
            Set<String> warfareNameSet = new HashSet<>(warfareName);
            warfareNameSet.retainAll(wordSet);
            log.info("匹配战争结果：{}", warfareNameSet);
            // 如果有交集  , 则判断是否包含"战役"  关键词
            if (words.contains("战役")) {
                if (warfareNameSet.isEmpty()) {
                    return "未收录该战役信息";
                }
                // 查询 战争下有的 战役
                List<QbWarfareExamples> warfareExamples = qbWarfareExamplesMapper.getWarfareExamplesByWarfareName(warfareNameSet);
                if (Collections.isEmpty(warfareExamples)) {
                    // 没有匹配到战役
                    StringBuilder res = new StringBuilder("未获取到:[");
                    for (String s : warfareNameSet) {
                        res.append(s);
                    }
                    res.append("] 对应下的战役信息，请重新提问");
                    return res.toString();
                }
                // 包含战役信息, 则填充一下
                return buildWarfareExampleResult(warfareExamples);
            }
            /*else {
                // 查询是否包含战役名称
                List<QbWarfareExamples> qbWarfareExamples = qbWarfareExamplesMapper.getWarfareExamplesByWarfareExampleName(words);
                String warfareExampleResult = buildWarfareExampleResult(qbWarfareExamples);
                if (!qbWarfareExamples.isEmpty()) {
                    return warfareExampleResult;
                }
            }*/

        }
        // 查询是否包含战役名称
        List<QbWarfareExamples> qbWarfareExamples = qbWarfareExamplesMapper.getWarfareExamplesByWarfareExampleName(words);
        String warfareExampleResult = buildWarfareExampleResult(qbWarfareExamples);
        if (!qbWarfareExamples.isEmpty()) {
            return warfareExampleResult;
        }
        return null;
    }

    private static String buildWarfareExampleResult(List<QbWarfareExamples> qbWarfareExamples) {
        StringBuilder res = new StringBuilder();
        for (QbWarfareExamples qbWarfareExample : qbWarfareExamples) {
            res.append(qbWarfareExample.getTitle());
            res.append("\n").append("\n");
            res.append(qbWarfareExample.getTranslation());
            res.append("\n").append("\n").append("\n").append("====================================================\n");
        }
        return res.toString();
    }
}
